<?php

namespace app\controllers\admin\uni\user;

use app\controllers\admin\base\AdminController;
use app\models\admin_ops\AdminOpsRefill;
use app\models\MonthProfit;
use app\models\NewLevel;
use app\models\order\Order;
use app\models\Transfer;
use app\models\user\User as Model;
use app\models\user\UserAccount;
use app\models\user\UserCash;
use app\models\user\UserCommission;
use app\models\user\UserConsume;
use app\models\user\UserLevel;
use app\models\user\UserPayPassword;
use app\models\UserDown;
use app\models\ZSetting;
use app\services\Chain;
use app\services\User;
use app\services\User as Service;
use app\util\Tree;
use yii\helpers\ArrayHelper;

/**
 * Class UserController
 * @package app\controllers\admin\uni\user
 */
class UserController extends AdminController
{

    // 团队排序
    public function actionUserSort()
    {
        $id = $this->post('id');
        $sort = $this->post('sort');
        $user = Model::findOne(['id' => $id]);
        if (!$user) {
            return $this->fail('操作错误');
        }

        $user->sort = $sort;
        if ($user->save()) {
            return $this->success();
        }

        return $this->fail();
    }

    public function actionUserReferrerList()
    {
        $list = $query = Model::find()
            ->where(['!=', 'status', Model::$statusMapping['DELETE']])
            ->orderBy(['id' => SORT_ASC])
            ->select(['id', 'mobile'])
            ->asArray()
            ->all();

        array_unshift($list, ['id' => 0, 'mobile' => '平台']);

        return $this->success($list);
    }

    public function actionList()
    {
        $id = $this->post('id');
        $status = $this->post('status');
        $export = $this->post('export');

        $mobile = $this->post('mobile');
        $nickname = $this->post('nickname');
        $referrer_id = $this->post('referrer_id');

        $level = $this->post('level');
        $new_level = $this->post('new_level');

        $page = intval($this->post('page', $this->page));
        $page_size = intval($this->post('pageSize', $this->pageSize));

        $sort = $this->post('sort');

        $query = Model::find()
            ->where(['!=', 'status', Model::$statusMapping['DELETE']])
            ->with(['referrer', 'level0', 'level2', 'account']);

        if ($status > Model::$statusMapping['ALL']) {
            $query->andWhere(['status' => $status]);
        }

        if ($sort) {
            $prop = substr($sort, 0, 1);
            $prop = $prop == '-' ? SORT_DESC : SORT_ASC;
            $order = substr($sort, 1);
            $query->orderBy([$order => $prop]);
        } else {
            $query->orderBy(['id' => SORT_DESC]);
        }

        if ($id) {
            $query->andWhere(['id' => $id]);
        }
        if (strlen($level)) {
            $query->andWhere(['level' => $level]);
        }
        if ($new_level > 0) {
            $query->andWhere(['new_level' => $new_level]);
        }
        if ($referrer_id) {
            $query->andWhere(['referrer_id' => $referrer_id]);
        }
        if ($mobile) {
            $query->andWhere(['like', 'mobile', $mobile]);
        }
        if ($nickname) {
            $query->andWhere(['like', 'nickname', $nickname]);
        }

        // export
        // if ($export) {
        //     $list = $query->asArray()->all();
        //     foreach ($list as &$item) {
        //         $item['nickname'] = base64_decode($item['nickname']);
        //         unset($item['password']);
        //     }
        //     return $this->success($list);
        // }

        // export
        if ($export) {
            $list = $query->asArray()->all();
            foreach ($list as &$item) {
                $item['nickname'] = base64_decode($item['nickname']);
                unset($item['password']);

                // 业绩
                $children = Chain::getChildrenAll($item['id']);
                $children = ArrayHelper::getColumn($children, 'id');
                $children = array_merge([$item['id']], $children);

                $item['my'] = Order::find()
                    ->where(['user_id' => $item['id']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                    ->sum('total_pay');
                $item['team'] = Order::find()
                    ->where(['user_id' => $children])
                    ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                    ->sum('total_pay');

                $item['my_order'] = Order::find()
                    ->where(['user_id' => $item['id']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                    ->count();
                $item['team_order'] = Order::find()
                    ->where(['user_id' => $children])
                    ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                    ->count();

                $item['team_count'] = count($children);

                // 佣金
                $item['x_commission'] = (float)UserCommission::find()
                    ->where(['user_id' => $id])
                    ->andWhere(['status' => 1])
                    ->sum('balance');

                // 充值
                $item['x_refill'] = (float)AdminOpsRefill::find()
                    ->where(['user_id' => $id])
                    ->sum('balance');

                // 消费
                $item['x_consume'] = (float)Order::find()
                    ->where(['user_id' => $id])
                    ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                    ->andWhere(['!=', 'status', Order::$statusMapping['REFUND']])
                    ->sum('use_balance');

                // 退款
                $item['x_refund'] = (float)UserAccount::find()
                    ->where(['user_id' => $id])
                    ->sum('balance');

                // 提现
                $item['x_cash'] = (float)UserCash::find()
                    ->where(['user_id' => $id])
                    ->andWhere(['status' => 1])
                    ->sum('amount');

            }
            return $this->success($list);
        }

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $page_size);

        $list = $query->offset(($page - 1) * $page_size)
            ->limit($page_size)
            ->asArray()
            ->all();
        foreach ($list as &$item) {
            unset($item['password']);
            $item['nickname'] = base64_decode($item['nickname']);

            $item['city'] = User::getCity($item);

            // 业绩
            $children = Chain::getChildrenAll($item['id']);
            $children = ArrayHelper::getColumn($children, 'id');
            $children = array_merge([$item['id']], $children);

            $item['my'] = Order::find()
                ->where(['user_id' => $item['id']])
                ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                ->sum('total_pay');
            $item['team'] = Order::find()
                ->where(['user_id' => $children])
                ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                ->sum('total_pay');

            $item['my_order'] = Order::find()
                ->where(['user_id' => $item['id']])
                ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                ->count();
            $item['team_order'] = Order::find()
                ->where(['user_id' => $children])
                ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                ->count();

            // 佣金
            $item['x_commission'] = (float)UserCommission::find()
                ->where(['user_id' => $item['id']])
                ->andWhere(['status' => 1])
                ->sum('balance');

            // 充值
            $item['x_refill'] = (float)AdminOpsRefill::find()
                ->where(['user_id' => $item['id']])
                ->sum('balance');

            // 消费
            $item['x_consume'] = (float)Order::find()
                ->where(['user_id' => $item['id']])
                ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
                ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
                ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
                ->andWhere(['!=', 'status', Order::$statusMapping['REFUND']])
                ->sum('use_balance');

            // 退款
            $item['x_refund'] = (float)UserAccount::find()
                ->where(['user_id' => $item['id']])
                ->sum('balance');

            // 提现
            $item['x_cash'] = (float)UserCash::find()
                ->where(['user_id' => $item['id']])
                ->andWhere(['status' => 1])
                ->sum('amount');

            $item['team_count'] = count($children);
        }

        return $this->success([
            $this->totalCount   => $totalCount,
            $this->totalPage    => $totalPage,
            $this->list         => $list,
        ]);

    }

    // 取消身份
    public function actionCancelCity()
    {
        $id = $this->post('id');

        $model = \app\models\user\User::findOne(['id' => $id]);
        if ($model) {
            $model->address_up = 0;
            $model->save();
        }

        return $this->success();
    }

    public function actionEdit()
    {
        $data = $this->post();

        // check referrer
        if (isset($data['referrer_id']) && $data['referrer_id'] > 0) {
            $referrer = Model::find()
                ->select(['id'])
                ->where(['id' => $data['referrer_id']])
                ->one();
            if (!$referrer) {
                return $this->fail('推荐人错误');
            }

            // referrer chain
            if (Service::checkReferrer($data['id'], $data['referrer_id'])) {
                return $this->fail('推荐人错误!!!');
            }
        }

        try {
            if (isset($data['id']) && $data['id'] > 0) {
                $model = Model::findOne(['id' => $data['id']]);
                if (!$model) {
                    return $this->fail('操作失败');
                }
            } else {
                // check mobile isExist
                $user = Model::findOne(['mobile' => $data['mobile']]);
                if ($user) {
                    return $this->fail('该手机号码已经存在!');
                }

                $model = new Model();
                $data['password'] = '123456';
            }

            // admin operation
            $model->admin_ops = 1;

            if ($data['nickname']) {
                $data['nickname'] = base64_encode($data['nickname']);
            }

            if (isset($data['level2'])) {
                $data['new_level'] = $data['level2'];
            }

            $data = ['User' => $data];
            if ($model->load($data) && $model->save()) {

                // user account
                $account = UserAccount::findOne(['user_id' => $model->id]);
                if (!$account) {
                    $account = new UserAccount();
                    $account->user_id = $model->id;
                    $account->save();
                }

                return $this->success($model, '操作成功');
            }
        } catch (\Exception $e) {
            return $this->fail($e->getMessage());
        }
    }

    public function actionView()
    {
        $id = $this->post('id');
        $model = Model::find()
            ->where(['id' => $id])
            ->with(['account'])
            ->asArray()
            ->one();

        if ($model) {
            // delete password
            unset($model['password']);

            $model['nickname'] = base64_decode($model['nickname']);

            return $this->success($model);
        }

        return $this->fail('不存在该会员');
    }

    public function actionRemove()
    {
        $id = $this->post('id');

        try {
            $model = Model::findOne(['id' => $id]);
            // $model->status = Model::$statusMapping['DELETE'];
            // $model->save();
            $model->delete();
            return $this->success($model, '删除成功');
        } catch (\Exception $e) {
            return $this->fail($e->getMessage());
        }
    }

    public function actionStatusList()
    {
        return $this->success(Model::statusList());
    }

    public function actionChangeStatus()
    {
        $id = intval($this->post('id'));
        $status = intval($this->post('status'));

        try {
            $model = Model::findOne(['id' => $id]);
            $model->status = $status;
            $model->save();

            return $this->success();
        } catch (\Exception $e) {
            return $this->fail('操作错误: ' . $e->getMessage());
        }
    }

    /**
     * User level list
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionLevelList()
    {
        $list = UserLevel::find()
            ->orderBy(['value' => SORT_ASC, 'id' => SORT_ASC])
            ->where(['!=', 'key', ''])
            ->andWhere(['!=', 'hide', 1])
            ->asArray()
            ->all();

        return $this->success($list);
    }

    // 新等级
    public function actionNewLevel()
    {
        $list = NewLevel::find()
            ->orderBy(['value' => SORT_ASC])
            ->asArray()
            ->all();

        // foreach ($list as &$item) {
        //     $item['value'] = intval($item['value']);
        // }

        return $this->success($list);
    }

    /**
     * User level edit
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionLevelEdit()
    {
        $data = $this->post();

        $model = UserLevel::findOne(['id' => $data['id']]);
        if ($model) {
            $model->display = $data['display'];
            if ($model->save()) {
                return $this->success();
            }
        }

        return $this->fail();
    }

    public function actionGetMain()
    {
        $id = $this->post('id');

        $my = Model::find()
            ->where(['id' => $id])
            ->with(['level0'])
            ->asArray()
            ->one();

        if ($my['nickname']) {
            $my['nickname'] = base64_decode($my['nickname']);

            // 直推多少个
            $my['count'] = Model::find()
                ->where(['referrer_id' => $id])
                ->count();
        }

        return $this->success([$my]);
    }

    // 懒加载
    public function actionTeamTreeNew()
    {
        $id = $this->post('id');

        $list = Chain::getChildrenTreeSort($id);

        foreach ($list as &$item) {
            if ($item['nickname']) {
                $item['nickname'] = base64_decode($item['nickname']);
            }
            // 直推多少个
            $item['count'] = Model::find()
                ->where(['referrer_id' => $item['id']])
                ->count();
        }

        return $this->success($list);
    }

    public function actionTeamTree()
    {
        $id = $this->post('id');

        $list = Chain::getChildrenAll($id);
        // nickname
        foreach ($list as &$item) {
            if ($item['nickname']) {
                $item['nickname'] = base64_decode($item['nickname']);
            }
        }

        $list = Tree::create($list, 'id', 'referrer_id', 'children', $id);

        $my = Model::find()
            ->where(['id' => $id])
            ->with(['level0'])
            ->asArray()
            ->one();
        $my['children'] = $list;

        if ($my['nickname']) {
            $my['nickname'] = base64_decode($my['nickname']);
        }

        return $this->success([$my]);
        return $this->success($list);
    }

    public function actionAdminRefill()
    {
        $user_id = intval($this->post('user_id'));
        $balance = intval($this->post('balance'));
        $score = intval($this->post('score'));
        $ticket = intval($this->post('ticket'));
        $platform_ticket = intval($this->post('platform_ticket'));

        $account = UserAccount::findOne(['user_id' => $user_id]);
        if (!$account) {
            return $this->fail('帐户错误');
        }

        $transaction = \Yii::$app->db->beginTransaction();
        try {
            $model = new AdminOpsRefill();
            $model->user_id = $user_id;
            $model->balance = $balance;
            $model->score = $score;
            $model->ticket = $ticket;
            $model->platform_ticket = $platform_ticket;
            $model->save();

            $account->balance += $balance;
            $account->score += $score;
            $account->ticket += $ticket;
            $account->platform_ticket += $platform_ticket;
            $account->save();

            $transaction->commit();
            return $this->success();
        } catch (\Exception $e) {
            $transaction->rollBack();
            return $this->fail();
        }
    }

    public function actionAdminRefillList()
    {
        $user_id = intval($this->post('user_id'));

        $list = AdminOpsRefill::find()
            ->where(['user_id' => $user_id])
            ->orderBy(['id' => SORT_DESC])
            ->asArray()
            ->all();

        return $this->success($list);
    }

    public function actionCommission()
    {
        $page = intval($this->post('page', $this->page));
        $page_size = intval($this->post('pageSize', $this->pageSize));

        $user_id = $this->post('user_id');

        $query = UserCommission::find()
            ->where(['user_id' => $user_id]);

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $page_size);

        $list = $query->offset(($page - 1) * $page_size)
            ->limit($page_size)
            ->orderBy(['id' => SORT_DESC])
            ->asArray()
            ->all();

        return $this->success([
            $this->totalCount   => $totalCount,
            $this->totalPage    => $totalPage,
            $this->list         => $list,
        ]);
    }

    public function actionConsume()
    {
        $page = intval($this->post('page', $this->page));
        $page_size = intval($this->post('pageSize', $this->pageSize));

        $user_id = $this->post('user_id');

        $query = UserConsume::find()
            ->where(['user_id' => $user_id]);

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $page_size);

        $list = $query->offset(($page - 1) * $page_size)
            ->limit($page_size)
            ->orderBy(['id' => SORT_DESC])
            ->asArray()
            ->all();

        return $this->success([
            $this->totalCount   => $totalCount,
            $this->totalPage    => $totalPage,
            $this->list         => $list,
        ]);
    }

    // reset pay password
    public function actionResetPayPassword()
    {
        $id = $this->post('id');
        $model = UserPayPassword::findOne(['user_id' => $id]);
        if (!$model) {
            $model = new UserPayPassword();
            $model->user_id = $id;
        }
        $model->password = '123456';
        $model->save();

        return $this->success();
    }

    public function actionTransferList()
    {
        $export = $this->post('export');

        $page = intval($this->post('page', $this->page));
        $page_size = intval($this->post('pageSize', $this->pageSize));

        $user_id = $this->post('user_id');

        $query = Transfer::find();

        if ($user_id) {
            $query->where([
                'or',
                ['send_id' => $user_id],
                ['received_id' => $user_id],
            ]);
        }

        if ($export) {
            $list = $query->asArray()->all();
            return $this->success(
                $list
            );
        }

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $page_size);

        $list = $query->offset(($page - 1) * $page_size)
            ->limit($page_size)
            ->orderBy(['id' => SORT_DESC])
            ->asArray()
            ->all();

        return $this->success([
            $this->totalCount   => $totalCount,
            $this->totalPage    => $totalPage,
            $this->list         => $list,
        ]);
    }

    public function actionZList()
    {
        $list = ZSetting::find()
            ->orderBy(['id' => SORT_ASC])
            ->asArray()
            ->all();

        return $this->success($list);
    }

    public function actionZEdit()
    {
        $data = $this->post();

        $model = ZSetting::findOne(['id' => $data['id']]);
        if ($model) {
            $model->start = $data['start'];
            $model->end = $data['end'];
            $model->amount = $data['amount'];
            if ($model->save()) {
                return $this->success();
            }
        }

        return $this->fail();
    }

    public function actionProfitList()
    {
        $list = MonthProfit::find()
            ->orderBy(['id' => SORT_ASC])
            ->asArray()
            ->all();

        return $this->success(['list' => $list]);
    }

    public function actionDown()
    {
        $page = intval($this->post('page', $this->page));
        $page_size = intval($this->post('pageSize', $this->pageSize));

        $query = UserDown::find()
            ->orderBy(['id' => SORT_DESC]);

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $page_size);

        $list = $query->offset(($page - 1) * $page_size)
            ->limit($page_size)
            ->with(['old', 'new'])
            ->asArray()
            ->all();

        return $this->success([
            $this->totalCount   => $totalCount,
            $this->totalPage    => $totalPage,
            $this->list         => $list,
        ]);
    }
}